/**********************************************************

file:  Xbee.c

Author:	  albert

**********************************************************/

#include "Xbee.h"
#include "Timer.h"
#include "atmega128_usart.h"

unsigned char xbee_temp = 0;
unsigned char xbee_usart_num = 0;
unsigned char xbee_usart_high_speed = 1; //0->9600db 1->38400db

//only has AT and CMD, not parameters
struct AT_CMD
{
	unsigned char cmd_mode[3];
	unsigned char end_device_assoc[4];
	//should be 0 for end device, default is 0
	unsigned char data_rate[4]; //3 for 9600, 5 for 38400
	unsigned char channel[4]; //0x0B-0x1A
	unsigned char Dest_addr_high[4]; //0 FOR 16bit
	unsigned char Dest_addr_low[4];
	unsigned char my_addr[4]; // 0-0xFFFF
	unsigned char carriage_return[1];
	unsigned char line_feed[1];
	unsigned char ret[3];
	unsigned char exit_cmd[5];
} xbee_cmd =
{
	{
		0x2B, 0x2B, 0x2B //+++
	}
	,
	{
		0x41, 0x54, 0x41, 0x31
	}
	,
	{
		0x41, 0x54, 0x42, 0x44 //ATBD
	}
	,
	{
		0x41, 0x54, 0x43, 0x48
	}
	,
	{
		0x41, 0x54, 0x44, 0x48
	}
	,
	{
		0x41, 0x54, 0x44, 0x4C
	}
	,
	{
		0x41, 0x54, 0x4D, 0x59
	}
	,
	{
		0xCD
	}
	,
	{
		0x0D
	}
	,
	{
		0x4F, 0x4B, 0x0D
		//in win7 is 6f 6b
	}
	,
	{
		0x41, 0x54, 0x43, 0x4E, 0x0D //ATCN
	}
};


/********************************************************
*                                                       *
* CMD integrate                                        *
*                                                       *
********************************************************/
void cmd_integrate(unsigned char at_cmd[], unsigned int size_of_at_cmd, unsigned char parameter[], unsigned int size_of_par, unsigned char add_LF,
unsigned char call_write_usart_func)
{
	//add_LR true = 1, false = 0
	volatile unsigned char total_size = size_of_at_cmd + size_of_par + add_LF;
	unsigned char final_cmd[10];
	unsigned int n = 0;
	for (; n < size_of_at_cmd; n++)
	{
		final_cmd[n] = at_cmd[n];
	}
	for (; n < size_of_at_cmd + size_of_par; n++)
	{
		final_cmd[n] = parameter[n - size_of_at_cmd];
	}
	if (add_LF)
	{
		final_cmd[n] = xbee_cmd.line_feed[0];
	}

	if (call_write_usart_func)
	{
		USART_BYTES_Transmit(xbee_usart_num, final_cmd, total_size);
	}

}

/**************************************************************************
*                                                                        *
**************************************************************************/

unsigned char xbee_return_value_chk(void)
{

	if (usart_mode == 0)
	{
		while (usart0_count != 3)
		{

			USART_Receive(xbee_usart_num);
		}


	}
	else
	{
		Timer1_TwoSecond();
		while (usart0_count != 3 && timer_tick == 0)
		;
	}
	for (xbee_temp = 0; xbee_temp < 3; xbee_temp++)
	{
		if (usart0_rec_buff[xbee_temp] != xbee_cmd.ret[xbee_temp])
		return 0;
		else
		return 1;
	}
	return 0;

}

/********************************************************
*                                                       *
* Xbee configuration                                    *
*                                                       *
********************************************************/
unsigned char Xbee_config_init(void)
{
	_delay_ms(1000); //1S guard time
	//STEP 1
	usart0_count = 0;
	USART_BYTES_Transmit(xbee_usart_num, xbee_cmd.cmd_mode, sizeof(xbee_cmd.cmd_mode));
	//if xbee fails to enter cmd mode, possibility is the usart speed
	if (!xbee_return_value_chk())
	{
		if (xbee_usart_high_speed == 1)
		USART_INIT(xbee_usart_num, usart_mode,BAUDRATE_38400); //set to high speed
		usart0_count = 0;
		USART_BYTES_Transmit(xbee_usart_num, xbee_cmd.cmd_mode, sizeof(xbee_cmd.cmd_mode));
		if (!xbee_return_value_chk()) //still fail, return with error
		return  - 1;
	}
	//STEP 2 CH10
	unsigned char parameter[2] =
	{
		0x31, 0x30
	};
	usart0_count = 0;
	cmd_integrate(xbee_cmd.channel, sizeof(xbee_cmd.channel), parameter, sizeof(parameter), 1, 1);
	if (!xbee_return_value_chk())
	return  - 1;

	//STEP 3, Set the MY to 0x02
	parameter[0] = 0x30;
	parameter[1] = 0x32;
	usart0_count = 0;
	cmd_integrate(xbee_cmd.my_addr, sizeof(xbee_cmd.my_addr), parameter, sizeof(parameter), 1, 1);
	if (!xbee_return_value_chk())
	return  - 1;

	//STEP 4,Set the Destination add to 0x01
	parameter[0] = 0x30;
	parameter[1] = 0x31;
	usart0_count = 0;
	cmd_integrate(xbee_cmd.Dest_addr_low, sizeof(xbee_cmd.Dest_addr_low), parameter, sizeof(parameter), 1, 1);
	if (!xbee_return_value_chk())
	return  - 1;
	//STEP 5,Set the Xbee speed to 38400
	if (xbee_usart_high_speed == 1)
	{
		usart0_count = 0;
		parameter[0] = 0x30;
		parameter[1] = 0x35;
		cmd_integrate(xbee_cmd.data_rate, sizeof(xbee_cmd.data_rate), parameter, sizeof(parameter), 1, 1);
		if (!xbee_return_value_chk())
		return  - 1;
	}
	//STEP6, Return from cmd mode
	usart0_count = 0;
	USART_BYTES_Transmit(xbee_usart_num, xbee_cmd.exit_cmd, sizeof(xbee_cmd.exit_cmd));
	if (!xbee_return_value_chk())
	return  - 1;
	//Reconfig thee USART
	if (xbee_usart_high_speed == 1)
	{
		USART_INIT(xbee_usart_num, usart_mode,BAUDRATE_38400);
	}

	return 1;

}


